# -*- coding: utf-8 -*-
"""
Tencent is pleased to support the open source community by making 蓝鲸智云PaaS平台社区版 (BlueKing PaaS Community
Edition) available.
Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved.
Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://opensource.org/licenses/MIT
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
specific language governing permissions and limitations under the License.
"""
import logging
import json
from django.core.paginator import Paginator
from django.shortcuts import render
from django.template.defaulttags import register
from django.http import JsonResponse
from api_application.base_api import BaseApi
from .models import Records, NameList

logger = logging.getLogger('auditLogger')

"""
    配置平台接口信息
    https://apigw.paas-edu.bktencent.com/docs/component-api/default/CC/intro
"""
bk_cmdb_api = BaseApi()

OS_TYPE = {"1": "Linux", "2": "Windows", "3": "AIX"}
PLATFORMS = dict(Records.PLATFORMS)
OPER_METHOD = dict(Records.OPER_METHOD)


# 开发框架中通过中间件默认是需要登录态的，如有不需要登录的，可添加装饰器login_exempt
# 装饰器引入 from blueapps.account.decorators import login_exempt
def home(request):
    """
    首页  配置页
    """
    # 查询业务
    # 默认查询未归档业务  查询已归档业务：{"condition": {"bk_data_status": "disabled"}}
    # bizs = bk_cmdb_api.requests("POST", "search_business", {
    # "fields": ["bk_biz_id", "bk_biz_name"]
    # })
    # biz_infos = bizs["data"]["info"] if bizs.get("result", False) else []
    # biz_infos.append({"bk_biz_id": 0, "bk_biz_name": "未分配"})
    # return render(request, "home_application/index_home.html", {"bizs": biz_infos})
    return render(request, "home_application/index_home.html", {"os_type": json.dumps(OS_TYPE)})


def search_business(request):
    """
    # 查询业务
    """
    bizs = bk_cmdb_api.requests("POST", "search_business")
    name_list = NameList.objects.filter().first().name_list
    black_bizs = name_list.get("black_bizs")
    if not black_bizs: black_bizs = [2, 3, 11, 12, 13]

    biz_infos = bizs["data"]["info"] if bizs.get("result", False) else []
    bizs = [item for item in biz_infos if (item['bk_biz_id'] not in black_bizs)]
    return JsonResponse({"bizs": bizs})


def list_biz_hosts(request):
    # 查询业务下的主机，获取当前业务的主机列表
    params = json.loads(request.body)
    bk_biz_id = params.get("bk_biz_id", None)
    data = {
        "total": 0,
        "free_nums": 0,  # 空闲机池数
        "resource_nums": 0,  # 资源池主机数
        "hosts": []
    }
    if bk_biz_id:
        resp = bk_cmdb_api.requests("POST", "list_biz_hosts", {
            "page": {"start": params.get("start", 0), "limit": params.get("length", 20), "sort": "bk_host_id"},
            "bk_biz_id": bk_biz_id,
            "fields": ["bk_host_id", "bk_cloud_id", "bk_host_innerip", "bk_os_type", "bk_mac"]
        })
        if resp.get("result", False):
            data["total"] = resp["data"]["count"]
            data["hosts"] = resp["data"]["info"]

        # 空闲机

        # 查询资源池中的主机
        list_resource_pool_hosts = bk_cmdb_api.requests("POST", "list_resource_pool_hosts", {
            "page": {
                "start": 0, "limit": 10, "sort": "bk_host_id"
            },
            "fields": [
                "bk_host_id", "bk_cloud_id", "bk_host_innerip", "bk_os_type", "bk_mac"
            ],
        })
        data["resource_nums"] = list_resource_pool_hosts["data"]["count"]

    # elif 0 == bk_biz_id:
    #     # 没有业务ID的主机查询
    #     list_hosts_without_biz = bk_cmdb_api.requests("POST", "list_hosts_without_biz", {"page": {"start": 0, "limit": 100}, "fields": [
    #         "bk_host_id",
    #         "bk_cloud_id",
    #         "bk_host_innerip",
    #         "bk_os_type",
    #         "bk_mac"
    #     ]})
    #     if list_hosts_without_biz.get("result", False):
    #         data["total"] = list_hosts_without_biz["data"]["count"]
    #         data["hosts"] = list_hosts_without_biz["data"]["info"]
    return JsonResponse(data)


def list_biz_hosts_topo(request):
    # 查询业务下的主机和拓扑信息  https://bkapi.paas-edu.bktencent.com/api/c/compapi/v2/cc/list_biz_hosts_topo/
    pramas = json.loads(request.body)
    bk_biz_id = pramas.get("bk_biz_id", None)
    bk_biz_name = pramas.get("bk_biz_name", "业务名称")
    start = pramas.get("start", 0)
    length = pramas.get("length", 100)
    resp = bk_cmdb_api.requests("POST", "list_biz_hosts_topo", {
        "page": {
            "start": start,
            "limit": length
        },
        "bk_biz_id": bk_biz_id,
        "fields": [
            "bk_host_id",
            "bk_cloud_id",
            "bk_host_innerip",
            "bk_os_type",
            "bk_mac"
        ]
    })
    res = resp["data"]["info"]
    children = []
    for item in res:
        sub_children = []
        for item2 in item["topo"]:
            subsub_children = []
            for item3 in item2["module"]:
                subsub_children.append({
                    "name": f'模：[{item3["bk_module_id"]}] {item3["bk_module_name"]}',
                    # "value": 1
                })
            sub_children.append({
                "name": f'集：[{item2["bk_set_id"]}] {item2["bk_set_name"]}',
                "children": subsub_children
            })
        children.append({
            # item["bk_mac"] item["bk_os_type"]
            "name": f'主机：[{item["host"]["bk_host_id"]}] {item["host"]["bk_host_innerip"]}',
            "children": sub_children
        })

    data = {
        "name": f"业：{bk_biz_name}",
        "children": children
    }
    return JsonResponse(data)


def get_host_base_info(request):
    """
    获取主机详情
    https://apigw.paas-edu.bktencent.com/docs/component-api/default/CC/get_host_base_info/doc
    """
    bk_host_id = request.GET.get("bk_host_id", 0)
    host_info = bk_cmdb_api.requests("POST", "get_host_base_info", {
        "bk_host_id": bk_host_id
    })
    host_info["fields"] = {
        "bk_host_innerip": "内网IP", "bk_host_outerip": "外网IP", "bk_os_type": "操作系统类型", "bk_host_name": "主机名称",
        "bk_os_version": "系统版本", "bk_os_name": "系统名称", "bk_cpu": "CPU核心", "bk_os_bit": "系统位数", "bk_cpu_module": "CPU型号",
        "bk_mem": "内存大小", "bk_disk": "磁盘大小", "bk_mac": "MAC地址", "create_time": "创建时间", "bk_cpu_architecture": "CPU架构",
        "bk_host_innerip_v6": "内网IPv6", "bk_host_outerip_v6": "外网IPv6", "bk_agent_id": "GSE Agent ID", "bk_outer_mac": "外网MAC地址",
        "bk_cloud_vendor": "云厂商", "bk_cloud_host_status": "云主机状态", "bk_cloud_inst_id": "云实例ID", "bk_state": "状态",
        "import_from": "来源", "bk_province_name": "省份名称", "bk_cloud_id": "云区域ID", "bk_sn": "序列号"
    }
    host_info["os_type"] = OS_TYPE
    return render(request, "home_application/asset_infos.html", host_info)


def clone_host_property(request):
    """
    机器属性管理 克隆主机属性
    https://apigw.paas-edu.bktencent.com/docs/component-api/default/CC/clone_host_property/doc
    "bk_biz_id":2,   业务ID
    "bk_org_id": 10,  源主机ID
    "bk_dst_id": 11,  目标主机ID
    "bk_cloud_id":0   否 云区域ID
    或
    "bk_biz_id": 2,  # 业务ID
    "bk_org_ip": "127.0.0.1",  # 源主机内网ip
    "bk_dst_ip": "127.0.0.2",  # 目标主机内网ip
    "bk_cloud_id": 0 # 否 云区域ID
    注： 使用主机内网IP进行克隆与使用主机身份ID进行克隆，这两种方式只能使用期中的一种，不能混用。
    """
    params = json.loads(request.body)
    bk_biz_id = params.get("bk_biz_id", None)

    bk_org_ip = params.get("bk_org_ip", None)
    bk_dst_ip = params.get("bk_dst_ip", None)
    bk_org_id = params.get("bk_org_id", None)
    bk_dst_id = params.get("bk_dst_id", None)
    results = {}
    if bk_biz_id:
        record = Records()
        record.save(request=request, params=params)
        if bk_org_ip and bk_dst_ip:
            results = bk_cmdb_api.requests("POST", "clone_host_property", {
                "bk_biz_id": bk_biz_id,
                "bk_org_ip": bk_org_ip,
                "bk_dst_ip": bk_dst_ip,
            })
        elif bk_org_id and bk_dst_id:
            results = bk_cmdb_api.requests("POST", "clone_host_property", {
                "bk_biz_id": bk_biz_id,
                "bk_org_id": bk_org_id,
                "bk_dst_id": bk_dst_id,
            })
    return JsonResponse(results)


# 模块转移
def transfer_host_module(request):
    """
    # 业务内主机转移模块
    "bk_biz_id": 1,   业务ID
    "bk_host_id": [   主机ID
        9,
        10
    ],
    "bk_module_id": [  模块ID
        10
    ],
    "is_increment": true  覆盖或者追加,会删除原有关系. true是更新，false是覆盖
    """

    req_params = json.loads(request.body)
    data = {}
    if isinstance(req_params, dict):
        record = Records()
        record.save(request=request, params=req_params)
        data = bk_cmdb_api.requests("POST", "transfer_host_module", req_params)
    return JsonResponse(data)


def create_business(request):
    # 创建业务
    return


def delete_business(request):
    # 删除业务
    return


def batch_delete_business_set(request):
    # 批量删除业务集
    return


def set_operator(request):
    """
    集群操作
    """
    params = json.loads(request.body)
    bk_biz_id = params.get("bk_biz_id", None)
    bk_set_id = params.get("bk_set_id", None)
    bk_set_name = params.get("bk_set_name", None)
    description = params.get("description", "")
    bk_set_desc = params.get("bk_set_desc", "")
    if "POST" == request.method:
        # 创建集群
        resp = bk_cmdb_api.requests("POST", "create_set", {
            "bk_biz_id": bk_biz_id,
            "data": {
                "bk_parent_id": bk_biz_id,  # 父节点的ID
                "bk_set_name": bk_set_name,  # 集群名字
                "bk_set_desc": bk_set_desc,
                # "bk_capacity": 1000,
                "description": description,
                # "set_template_id": 1  # 集群模板ID，需要通过集群模板创建集群时必填
            }
        })
    elif "DELETE" == request.method:
        # 删除集群
        resp = bk_cmdb_api.requests("POST", "delete_set", {
            "bk_biz_id": bk_biz_id,  # 业务id
            "bk_set_id": bk_set_id  # 集群id
        })
    elif "PATCH" == request.method:
        # 更新集群
        resp = bk_cmdb_api.requests("POST", "update_set", {
            "bk_biz_id": bk_biz_id,
            "bk_set_id": bk_set_id,
            "data": {
                "bk_set_name": bk_set_name  # 集群名字
            }
        })
    record = Records()
    record.save(request=request, params=params)
    return JsonResponse(resp)


def batch_delete_set(request):
    # 批量删除集群
    return


def find_set_batch(request):
    # 批量查询某业务的集群详情
    pass


def module_operator(request):
    """
    模块操作
    """
    params = json.loads(request.body)
    bk_biz_id = params.get("bk_biz_id", None)
    bk_set_id = params.get("bk_set_id", None)
    bk_module_id = params.get("bk_module_id", None)
    bk_module_name = params.get("bk_module_name", None)
    if "POST" == request.method:
        # 创建模块
        resp = bk_cmdb_api.requests("POST", "create_module", {
            "bk_biz_id": bk_biz_id,
            "bk_set_id": bk_set_id,
            "data": {
                "bk_parent_id": bk_set_id,
                "bk_module_name": bk_module_name
            }
        })
    elif "DELETE" == request.method:
        # 删除模块
        resp = bk_cmdb_api.requests("POST", "delete_module", {
            "bk_biz_id": bk_biz_id,
            "bk_set_id": bk_set_id,
            "bk_module_id": bk_module_id
        })
    elif "PATCH" == request.method:
        # 更新模块
        resp = bk_cmdb_api.requests("POST", "update_module", {
            "bk_biz_id": bk_biz_id,
            "bk_set_id": bk_set_id,
            "bk_module_id": bk_module_id,
            "data": {
                "bk_module_name": bk_module_name
            }
        })
    # elif "GET" == request.method:
    #     # 查询模块
    #     resp = bk_cmdb_api.requests("POST", "search_module", {
    #     })
    record = Records()
    record.save(request=request, params=params)
    return JsonResponse(resp)


def find_module_batch(request):
    # 批量查询某业务的模块详情
    return


def find_host_biz_relations(request):
    # 查询主机业务关系信息 https://bkapi.paas-edu.bktencent.com/api/c/compapi/v2/cc/find_host_biz_relations/
    bk_cmdb_api.requests("POST", "find_host_biz_relations", {
        "bk_biz_id": 1,  # 否 业务ID
        "bk_host_id": [  # 主机ID数组，ID个数不能超过500
            3,
            4
        ]
    })
    return JsonResponse()


def search_biz_inst_topo(request):
    # 查询业务实例拓扑
    params = json.loads(request.body)
    bk_biz_id = params.get("bk_biz_id", None)
    data = {}
    if bk_biz_id:
        # 查询业务实例拓扑
        res = bk_cmdb_api.requests("POST", "search_biz_inst_topo", {"bk_biz_id": bk_biz_id})
        if res['result'] == True:
            data = res['data'][0]

    # 查询业务的空闲机/故障机/待回收模块
    # get_biz_internal_module = bk_cmdb_api.requests("POST", "get_biz_internal_module", {"bk_biz_id": bk_biz_id})
    # data.update(get_biz_internal_module.get("data"))
    return JsonResponse(data)


def find_topo_node_paths(request):
    # 查询业务拓扑节点的拓扑路径  https://bkapi.paas-edu.bktencent.com/api/c/compapi/v2/cc/find_topo_node_paths/
    bk_cmdb_api.requests("POST", "find_topo_node_paths", {
        "bk_biz_id": 3,
        "bk_nodes": [  # 要查询的业务拓扑实例节点信息列表, 最大查询数量为1000
            {
                "bk_obj_id": "set",  # 业务拓扑节点模型名称，如biz,set,module及自定义层级模型名
                "bk_inst_id": 11  # 该业务拓扑节点的实例ID
            },
            {
                "bk_obj_id": "module",
                "bk_inst_id": 60
            },
            {
                "bk_obj_id": "province",
                "bk_inst_id": 3
            }
        ]
    })
    return


# create_cloud_area 创建云区域
# update_cloud_area 更新云区域

def host_operator(request):
    # add_host_to_resource 新增主机到资源池
    # add_host_to_resource_pool 添加主机到资源池
    # delete_host 删除主机
    pass


def transfer_host_to_faultmodule(request):
    # 上交主机到业务的故障机模块
    pass

def transfer_host_to_idlemodule(request):
    # 上交主机到业务的空闲机模块
    pass

def transfer_host_to_recyclemodule(request):
    # 上交主机到业务的待回收模块
    pass

def transfer_host_to_resourcemodule(request):
    # 上交主机至资源池
    pass

def update_host(request):
    # 更新主机属性
    bk_cmdb_api.requests("POST", "update_host", {
        "bk_host_id": "1,2,3",  # 主机ID，多个以逗号分隔
        "data": {
            "bk_host_name": "test"
        }
    })
    return


def batch_update_host(request):
    # 批量更新主机属性
    return


def find_host_by_topo(request):
    # 查询拓扑节点下的主机
    bk_cmdb_api.requests("POST", "find_host_by_topo", {
        "bk_biz_id": 5,
        "bk_obj_id": "xxx",  # 拓扑节点模型ID，不可为biz
        "bk_inst_id": 10,  # 拓扑节点实例ID
        "fields": [  # 主机属性列表，控制返回结果的主机里有哪些字段，能够加速接口请求和减少网络流量传输
            "bk_host_id",
            "bk_cloud_id"
        ],
        "page": {
            "start": 0,
            "limit": 10
        }
    })
    return


def create_set_template(request):
    # 新建集群模板
    pass


def batch_delete_inst(request):
    # 批量删除实例
    return


def find_host_relations_with_topo(request):
    # 根据业务拓扑中的实例节点查询其下的主机关系信息
    return


def find_host_topo_relation(request):
    # 获取主机与拓扑的关系
    return


def create_process_instance(request):
    # 创建进程实例
    pass


def record_page(request):
    """
    操作记录页面
    """
    return render(request, "home_application/record.html", {"platform": json.dumps(PLATFORMS), "oper_method": json.dumps(OPER_METHOD)})


def record_lists(request):
    """
    操作记录日志内容
    """
    start, length = 0, 30
    try:
        params = json.loads(request.body)
        start = params.get("start", 0)
        length = params.get("length", 30)
    except:
        pass
    page = start / length + 1
    records = Records.objects.all().order_by('-oper_datetime')
    paginator = Paginator(records, length)
    data = []

    for item in paginator.get_page(page):
        data.append({"id": item.id,
                     "platform": item.platform,
                     "oper_name": item.oper_name,
                     "oper_ip": item.oper_ip,
                     "oper_datetime": item.oper_datetime.strftime("%Y-%m-%d %H:%M:%S"),
                     "plat_module": item.plat_module,
                     "oper_method": item.oper_method,
                     "params": str(item.params)})
    return JsonResponse({
        "records_total": records.count(),
        "records": data
    })


# 编写自定义模板过滤
@register.filter
def get_item(dict: dict, key):
    return dict.get(key, key)
